package com.decent.sms.utils;

import com.decent.sms.entity.bo.SendSmsBO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.decent.common.util.CreateOrderNoUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * 发送短信工具类
 *
 * @author wangyx
 */
@Slf4j
public final class SendSmsUtils {
    private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(10,
            ThreadUtil.newNamedThreadFactory("SendSmsUtils-%d", true));

    /**
     * 发送短信业务
     *
     * @param sms 短信发送信息
     */
    public static void sendMsg(SendSmsBO sms) {
        EXECUTOR.execute(() -> {
            if (!PhoneUtil.isMobile(sms.getMobile())) {
                log.warn("发送短信验证手机号码失败[{}]", sms.getMobile());
                return;
            }
            String orderId = CreateOrderNoUtil.buildOrderNumber("sms");
            try {
                Map<String, Object> params = getRequestParam(sms, orderId);
                String post = HttpUtil.post(sms.getSendUrl(), params);
                log.info("[{}]发送短信反馈信息为[{}]", CollectionUtil.join(params.entrySet(), ","), post);
            } catch (IOException e) {
                log.error("[{}]短信发送异常", sms.getMobile(), e);
            }
        });
    }

    /**
     * 组装发送短信参数
     *
     * @param sms     基本信息
     * @param orderId 订单号
     * @return 短信入参
     * @throws UnsupportedEncodingException URL编码异常
     */
    private static Map<String, Object> getRequestParam(SendSmsBO sms, String orderId) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<>(8);
        params.put("account", sms.getYzxAccount());
        params.put("mobile", sms.getMobile());
        params.put("order_id", orderId);
        long timestamp = System.currentTimeMillis();
        params.put("time", timestamp + "");
        params.put("tpl_id", sms.getTemplateId());
        params.put("params", URLEncoder.encode(sms.getParams(), "UTF-8"));
        String source = sms.getMobile() + "|" + sms.getYzxAccount() + "|" + timestamp + "|" + sms.getTemplateId() + "#" + sms.getYzxSecret();
        String md5 = SecureUtil.md5(source).toUpperCase();
        params.put("sign", md5);
        return params;
    }
}
